//
//  main.m
//  07_内存管理
//
//  Created by dllo on 16/7/12.
//  Copyright © 2016年 LST. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Man.h"
int main(int argc, const char * argv[]) {
    /* 内存问题:
     * 内存溢出(泄露)
     * 内存过多导致溢出会产生Crash
     * 野指针 (过度释放)
     * 指针指向未知区域, 指向一块被释放的内存
     内存管理方式
     * 1.垃圾回收机制: 只有Mac上有
     * iOS
     * 2.MRC:手动管理引用计数
     * 3.ARC:自动管理引用计数(现在常用)
     * 注意:ARC基于MRC, 系统帮忙添加了内存管理的内容
     * 遇到 retain alloc copy 需要进行内存管理
     */
    /* MRC
     * 内存管理 : 引用计数(计数器)
     * 有retain alloc copy 会对引用计数+1
     * 有release autorelease 会对引用计数-1
     * 当对象的计数器为0的时候, 系统会调用对应的dealloc方法
     * 注意:内存管理, 你对对象操作完成后再进行释放
     */
    Man *man = [[Man alloc] init];
    NSLog(@"%ld", man.retainCount);
    [man retain];
    [man release];
    NSLog(@"%@-%ld", man, man.retainCount);
    // 集合类型会对对象进行引用计数
    // addObject 对对象进行引用计数 + 1
    // removeObject 对对象进行引用计数 - 1
    NSMutableArray *array = [NSMutableArray arrayWithObjects:man, nil];
    NSLog(@"向数组中添加后引用计数为:%ld", man.retainCount);
    [array removeAllObjects];
    NSLog(@"从数组中移除后的引用计数%ld", man.retainCount);
    
    /* ARC
     * strong(ARC, 强引用, 引用计数 + 1) weak(应用于对象类型(NSObject子类), 弱引用, 对象被释放的时候, 会自动置空)
     * retain(MRC, 强引用, 引用计数 + 1)
     * copy (拷贝, 把对象拷贝一份, 原来的引用计数不变, 新的 + 1)
     * assign(应用于简单的数据类型, 不会产生引用计数)
     */
    
    /* 协议 三步
     * 1.声明协议, 声明协议方法
     * 2.签订协议
     * 3.实现协议方法
     
     如果想实现对象的拷贝
     * 1.签订协议NSCopying
     * 2.实现协议方法 copyWithZone
     */
    Man *newMan = [man copy];
    NSLog(@"newMan = %@-oldMan : %@", newMan, man);
    newMan.name = @"含蓄";
    newMan.sexual = @"女";
    // KVC(NSObject) key Value Coding 键值编码 间接访问成员的方法
    // 只要是NSobject的子类就包含这些方法
    // valueForKey
    // setValue forKey
    // valueForKeyPath
    // setValue forKeyPath
    id name =[newMan valueForKey:@"name"];
    NSLog(@"%@", name);
    [newMan setValue:@"徐康" forKey:@"name"];
    NSLog(@"%@", newMan.name);
    Man *gayMan = [[Man alloc] init];
    gayMan.gayBoy = newMan;
    id boyName =[gayMan valueForKeyPath:@"gayBoy.name"];
    NSLog(@"---%@", boyName);
    [gayMan release];
    [gayMan setValue:@"李四" forKeyPath:@"gayBoy.name"];
    NSLog(@"%@", gayMan.gayBoy.name);
   
    NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"123456789", @"id", @"阿萨德", @"description", nil];
    Man * dicMan = [[Man alloc] init];
    [dicMan setValuesForKeysWithDictionary:dic];
    /* 
     * 加在Build Phases下编译source下
     * 如果在ARC工程下使用MRC文件
     * -fno-objc-arc
     * 在MRC的工程下使用ARC的文件
     * -fobjc-arc
     */
    
    return 0;
}









